package handler

import (
	"context"
	"fmt"
	"hertz/demo/biz/model"
	"hertz/demo/biz/mw"
	"hertz/demo/biz/util"
	"net/http"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/common/hlog"
)

func SyncSample(ctx context.Context, c *app.RequestContext) {
	var samples []model.Sample
	if err := c.BindAndValidate(&samples); err != nil {
		util.ErrMessage(c, http.StatusBadRequest, err.Error())
		return
	}

	conflicts, err := model.SyncSample(mw.GetDB(c), samples)
	if err != nil {
		hlog.CtxErrorf(ctx, "db error with sync sample: %w", err)
		util.ErrMessage(c, http.StatusInternalServerError, "db error")
		return
	}

	c.JSON(http.StatusOK, conflicts)
}

func ListSample(ctx context.Context, c *app.RequestContext) {
	stage := c.Query("stage")
	if stage != "" && !model.IsValidSampleStage(stage) {
		util.BadRequest(c, fmt.Errorf("invalid stage %s", stage))
		return
	}
	samples, err := model.ListSample(mw.GetDB(c), stage)
	if err != nil {
		hlog.CtxErrorf(ctx, "db error when list sample: %w", err)
		util.ErrMessage(c, http.StatusInternalServerError, "db error")
	}
	c.JSON(http.StatusOK, samples)
}

func GetSampleByID(ctx context.Context, c *app.RequestContext) {
	id := c.Param("id")
	if id == "" {
		util.BadRequest(c, fmt.Errorf("can't find param id"))
		return
	}
	sample, err := model.GetSampleByID(mw.GetDB(c), id)
	if err != nil {
		hlog.Errorf("GetSampleByID, id: %s, error: %w", err)
		util.ErrMessage(c, http.StatusInternalServerError, "db error")
		return
	}

	if sample == nil {
		util.NotFound(c)
		return
	}

	c.JSON(http.StatusOK, sample)
}

func GetSampleSelection(ctx context.Context, c *app.RequestContext) {
	id := c.Param("id")
	if id == "" {
		util.BadRequest(c, fmt.Errorf("can't find param id"))
		return
	}

	status := c.Query("status")
	if !model.IsValidSelectionStatus(status) {
		util.BadRequest(c, fmt.Errorf("invalid status: %s", status))
		return
	}

	author, err := util.GetQueryUintOption(c, "author")
	if err != nil {
		util.BadRequest(c, err)
		return
	}

	db := mw.GetDB(c)
	ret, err := model.ListSelection(db, id, status, author)
	if err != nil {
		hlog.CtxErrorf(ctx, "GetSampleSelection db error: %w", err)
		util.ErrMessage(c, http.StatusInternalServerError, "db error")
		return
	}

	c.JSON(http.StatusOK, ret)
}
